#!/usr/bin/env python
#参考文献
#https://www.codeleading.com/article/94802943145/
#http://t.zoukankan.com/xypbk-p-14841026.html
#https://docs.python.org/3/library/struct.html#format-characters
#https://blog.csdn.net/qq_45812612/article/details/109075452
import base64, struct #处理二进制、转换位字节
import numpy as np
from astropy.io import fits
import sys

f = open(sys.argv[1],'rb')

#读取文件头到数据之间的偏移字节数
f.seek(f.tell()+10) #跳过前面不需要的10位字节
file_ofset_byte = f.read(4) 
f_ofset, = struct.unpack('i', file_ofset_byte)

#读取图像尺寸
f.seek(f.tell()+4)
file_wide_byte = f.read(4)
file_height_byte = f.read(4)
f_wide, = struct.unpack('i', file_wide_byte)
f_height, = struct.unpack('i', file_height_byte)

#读取每个像素占位大小
f.seek(f.tell()+2)
file_bitcount_byte = f.read(4)
f_bitcount, = struct.unpack('i', file_bitcount_byte)
print('文件头偏置=', f_ofset,'图像宽度=', f_wide,'图像长度=', f_height,'位深度=', f_bitcount)

#读完文件头后读取颜色表
#因为BMP按照小端顺序排列所以是bgr，alpha设置透明度一般没有
color_table = np.empty(shape=[256,4], dtype=int)
f.seek(54) #跳过文件信息头和位图信息头
for i in range(0, 256):
    b = struct.unpack('B', f.read(1))[0]
    g = struct.unpack('B', f.read(1))[0]
    r = struct.unpack('B', f.read(1))[0]
    alpha = struct.unpack('B', f.read(1))[0]
    color_table[i][0] = r
    color_table[i][1] = g
    color_table[i][2] = b
    color_table[i][3] = 255

#接下来读取BMP位图数据区域，将数据存入numpy数组

#1.海康相机图像是8位伪彩色图像，一个像素占一个字节，即8位
#2.BMP数据排列方式是从左到右，从下到上
#3.内存的分配单位是4字节；位图中每个像素数据是连续的，但换行像素不能共用一个存储单元；#每个像素数据长度必须是4字节的倍数，不足时用后续字节用0补齐；所以需要判断行像素是否为4的倍数，若不是，要将填充字节读取扔掉

#直接通过设置文件指针偏移量读取数据
f.seek(f_ofset)
img = np.empty(shape=[f_height, f_wide, 4], dtype=int)
count = 0
#y循环每一列，x循环每一行
for y in range(0, f_height):
    for x  in range(0, f_wide):
        count = count + 1
        index = struct.unpack('B',f.read(1))[0]#转换成无符号字节（8位）
        img[f_height - y - 1, x] = color_table[index]
    while count % 4 != 0:
        f.fead(1)
        count = count + 1
f.close()
# save as fits file
img_data = img[:,:,0]
fits.writeto(sys.argv[2],data=img_data,overwrite=True)

